home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / emacs-18.59src.lha / emacs-18.59 / src / exec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-24  |  2.9 KB  |  139 lines

  1. #include "amiga.h"
  2. #include "processes.h"
  3. #include <amiga/ioctl.h>
  4. #include <exec/memory.h>
  5. #include <dos/dosextens.h>
  6. #include <dos/dostags.h>
  7. #include <string.h>
  8.  
  9. int eexec(char *program, char **argv, int input, int output, int error,
  10.       char *dir, int stacksize)
  11. /* input = -1 -> inherit Input()
  12.    output = -1 -> inherit Output()
  13.    error = -1 -> inherit pr_CES
  14.    error = -2 -> stderr = stdout */
  15. {
  16.   int index, comsize, close_input, close_output, close_error;
  17.   char *combuf, *bp;
  18.   BPTR in, out, err, dirlock;
  19.   int _pseudo_close(int fd);
  20.  
  21.   comsize = 256;
  22.   combuf = malloc(comsize);
  23.  
  24.   if (input == -1)
  25.     {
  26.       in = Input();
  27.       close_input = FALSE;
  28.     }
  29.   else
  30.     {
  31.       if (ioctl(input, _AMIGA_GET_FH, &in) == -1) in = 0;
  32.       close_input = TRUE;
  33.       _pseudo_close(input);
  34.     }
  35.  
  36.   if (output == -1)
  37.     {
  38.       out = Output();
  39.       close_output = FALSE;
  40.     }
  41.   else
  42.     {
  43.       if (ioctl(output, _AMIGA_GET_FH, &out) == -1) out = 0;
  44.       close_output = out != in;
  45.       _pseudo_close(output);
  46.     }
  47.  
  48.   if (error == -1)
  49.     {
  50.       err = _us->pr_CES;
  51.       close_error = FALSE;
  52.     }
  53.   else if (error == -2)
  54.     {
  55.       err = out;
  56.       close_error = FALSE;
  57.     }
  58.   else
  59.     {
  60.       if (ioctl(error, _AMIGA_GET_FH, &err) == -1) err = 0;
  61.       close_error = err != out && err != in;
  62.       _pseudo_close(error);
  63.     }
  64.  
  65.   /* pr_CES is not always defined */
  66.   if (in && out && (err || error == -1))
  67.     if (combuf)
  68.       {
  69.     bp = combuf;
  70.     for (index = 0; argv[index] != 0; index++)
  71.       {
  72.         /* Use program as argv[0]. This loses some information, but ... */
  73.         char *arg = index == 0 ? program : argv[index];
  74.         char *s;
  75.         int len;
  76.  
  77.         len = 3;
  78.         s = arg;
  79.         while (*s)
  80.           {
  81.         len++;
  82.         if (*s == '*' || *s == '"' || *s == '\n') len++;
  83.         s++;
  84.           }
  85.         if (bp + len + 1 >= combuf + comsize)
  86.           {
  87.         char *newbuf;
  88.  
  89.         comsize += comsize + len;
  90.         newbuf = realloc(combuf, comsize);
  91.         if (!newbuf) { errno = ENOMEM; goto error; }
  92.         bp = newbuf + (bp - combuf);
  93.         combuf = newbuf;
  94.           }
  95.         *bp++ = ' ';
  96.         *bp++ = '"';
  97.         s = arg;
  98.         while (*s)
  99.           {
  100.         if (*s == '"' || *s == '*') *bp++ = '*';
  101.         else if (*s == '\n') *bp++ = '+';
  102.         *bp++ = *s++;
  103.           }
  104.         *bp++ = '"';
  105.       }
  106.     *bp = '\0';
  107.     if (dir) dirlock = Lock(dir, SHARED_LOCK);
  108.     else dirlock = 0;
  109.  
  110.     if (dirlock || !dir)
  111.       {
  112.         int pid = _start_process(combuf, in, close_input, out, close_output,
  113.                      err, close_error, dirlock, stacksize);
  114.  
  115.         if (pid != -1)
  116.           {
  117.         free(combuf);
  118.         return pid;
  119.           }
  120.       }
  121.     else errno = convert_oserr(IoErr());
  122.     if (dirlock) UnLock(dirlock);
  123.       }
  124.     else errno = ENOMEM;
  125.  
  126.  error:
  127.   if (in && close_input) Close(in);
  128.   if (out && close_output) Close(out);
  129.   if (err && close_error) Close(err);
  130.   if (combuf) free(combuf);
  131.   return -1;
  132. }
  133.  
  134. int exec(char *program, char **argv, int input, int output, 
  135.       char *dir, int stacksize)
  136. {
  137.   return eexec(program, argv, input, output, -1, dir, stacksize);
  138. }
  139.